package com.sixkey.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sixkey.annotation.OperationLog;
import com.sixkey.config.ossconfig.OSSClient;
import com.sixkey.constant.CommonConstant;
import com.sixkey.constant.RabbitMQConstant;
import com.sixkey.entity.*;
import com.sixkey.entity.vo.ExportLog;
import com.sixkey.entity.vo.ExportReservation;
import com.sixkey.entity.vo.ExportRoom;
import com.sixkey.entity.vo.ExportUserVo;
import com.sixkey.exception.ServiceException;
import com.sixkey.rabbitmq.RabbitService;
import com.sixkey.response.Response;
import com.sixkey.response.ResponseEnum;
import com.sixkey.service.*;
import com.sixkey.utils.JodaTimeUtils;
import com.sixkey.utils.TimeStringUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.scheduling.annotation.Async;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * ClassName: CommonCotroller
 * Package: com.sixkey.controller
 * Description:
 *
 * @Author: @weixueshi
 * @Create: 2023/9/28 - 22:08
 * @Version: v1.0
 */
@Slf4j
@CrossOrigin
@RestController
@RequestMapping("/common")
@RequiredArgsConstructor
public class CommonController {

    private final IUserService userService;

    private final LogService logService;

    private final IRoomService roomService;

    private final IReservationService reservationService;

    /**
     * 头像上传接口
     * @param file
     * @return
     */
    @PostMapping("/upload")
    public Response upload(MultipartFile file){
        try {
            // 创建OSS实例
            OSS ossClient = new OSSClientBuilder().build(OSSClient.ENDPOINT, OSSClient.ACCESS_KEY, OSSClient.SECRET_KEY);
            log.info("文件开始上传...");
            // 获取文件原始名称
            String filename = file.getOriginalFilename();
            // 完善1、 --> 在文件名中添加唯一值
            String uuid = UUID.randomUUID().toString().replace("-", "");
            filename = uuid + filename;
            // 完善2、 --> 把文件按照日期分类
            String datePath = new DateTime().toString("yyyy/MM/dd");
            // 拼接时间 yyyy/MM/dd/filename
            filename = datePath + "/" + filename;
            ossClient.putObject(OSSClient.BUCKET_NAME, filename, file.getInputStream());
            log.info("文件上传成功...");
            String avatarUrl = "https://"+ OSSClient.BUCKET_NAME +"."+OSSClient.ENDPOINT+"/"+filename;
            return Response.success(avatarUrl);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 用户数据导出
     * @return
     */
    @GetMapping("/userExport")
    @OperationLog("用户数据导出")
    public void exportUserData(HttpServletResponse response){
        log.info("用户数据导出请求进来~");
        ServletOutputStream out= null;
        try {
            List<User> rows = userService.list();
            List<ExportUserVo> list = new ArrayList<>();
            rows.stream().forEach(item -> {
                ExportUserVo exUserVo = new ExportUserVo();
                exUserVo.setPhone(item.getPhone());
                exUserVo.setRole(item.getRole());
                exUserVo.setName(item.getName());
                list.add(exUserVo);
            });
            ExcelWriter writer = ExcelUtil.getWriter(true);
            writer.write(list, true);
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
            String fileName = URLEncoder.encode("用户数据","UTF-8");
            response.setHeader("Content-Disposition","attachment;filename="+fileName+".xlsx");
            out = response.getOutputStream();
            writer.flush(out, true);
            writer.close();
            IoUtil.close(out);
            log.info("用户数据导出成功~");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 用户数据导入
     * @return
     */
    @PostMapping("/userImport")
    @OperationLog("用户数据导入")
    public void importUserData(MultipartFile file) throws IOException {
        log.info("用户数据导入请求进来~");
        InputStream inputStream = file.getInputStream();
        ExcelReader reader = ExcelUtil.getReader(inputStream);
        //通过javabean的方式读取Excel内的对象，但是要求表头必须是英文，跟javabean的属性要对应起来
        List<ExportUserVo> lists = reader.readAll(ExportUserVo.class);
        List<User> userList = new ArrayList<>();
        lists.stream().forEach(item -> {
            User user = new User();
            user.setPhone(item.getPhone());
            user.setRole(item.getRole());
            user.setName(item.getName());
            userList.add(user);
        });
        //导入
        userList.stream().forEach(user -> {
            userService.save(user);
        });
        log.info("用户数据导入成功~");
    }

    /**
     * 日志数据导出
     * @return
     */
    @GetMapping("/logExport")
    @OperationLog("日志数据导出")
    public void exportLogData(HttpServletResponse response){
        log.info("日志数据导出请求进来~");
        ServletOutputStream out= null;
        try {
            List<Log> rows = logService.list();
            List<ExportLog> list = new ArrayList<>();
            rows.stream().forEach(item -> {
                ExportLog exportLog = new ExportLog();
                exportLog.setName(item.getName());
                exportLog.setIp(item.getIp());
                exportLog.setMethod(item.getMethod());
                exportLog.setOperation(item.getOperation());
                list.add(exportLog);
            });
            ExcelWriter writer = ExcelUtil.getWriter(true);
            writer.write(list, true);
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
            String fileName = URLEncoder.encode("用户操作日志数据","UTF-8");
            response.setHeader("Content-Disposition","attachment;filename="+fileName+".xlsx");
            out = response.getOutputStream();
            writer.flush(out, true);
            writer.close();
            IoUtil.close(out);
            log.info("日志数据导出成功~");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 会议室数据导出
     * @return
     */
    @GetMapping("/roomExport")
    @OperationLog("会议室数据导出")
    public void exportRoomData(HttpServletResponse response){
        log.info("日志数据导出请求进来~");
        ServletOutputStream out= null;
        try {
            List<Room> rows = roomService.list();
            List<ExportRoom> list = new ArrayList<>();
            rows.stream().forEach(item -> {
                ExportRoom exportRoom = new ExportRoom();
                exportRoom.setName(item.getName());
                exportRoom.setLocation(item.getLocation());
                exportRoom.setDescription(item.getDescription());
                exportRoom.setCapacity(item.getCapacity());
                exportRoom.setStatus(item.getStatus());
                exportRoom.setImage(item.getImage());
                list.add(exportRoom);
            });
            System.out.println(list);
            ExcelWriter writer = ExcelUtil.getWriter(true);
            writer.write(list, true);
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
            String fileName = URLEncoder.encode("会议室数据","UTF-8");
            response.setHeader("Content-Disposition","attachment;filename="+fileName+".xlsx");
            out = response.getOutputStream();
            writer.flush(out, true);
            writer.close();
            IoUtil.close(out);
            log.info("会议室数据导出成功~");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 会议室数据导入
     * @return
     */
    @PostMapping("/roomImport")
    @OperationLog("会议室数据导入")
    public void importRoomData(MultipartFile file) throws IOException {
        log.info("会议室数据导入请求进来~");
        InputStream inputStream = file.getInputStream();
        ExcelReader reader = ExcelUtil.getReader(inputStream);
        //通过javabean的方式读取Excel内的对象，但是要求表头必须是英文，跟javabean的属性要对应起来
        List<ExportRoom> lists = reader.readAll(ExportRoom.class);
        List<Room> roomList = new ArrayList<>();
        lists.stream().forEach(item -> {
            Room room = new Room();
            room.setName(item.getName());
            room.setLocation(item.getLocation());
            room.setDescription(item.getDescription());
            room.setCapacity(item.getCapacity());
            room.setStatus(item.getStatus());
            room.setImage(item.getImage());
            roomList.add(room);
        });
        //导入
        roomList.stream().forEach(room -> {
            roomService.save(room);
        });
        log.info("会议室数据导入成功~");
    }

    /**
     * 会议数据导出
     * @return
     */
    @GetMapping("/reservationExport")
    @OperationLog("会议数据导出")
    public void exportReservationData(HttpServletResponse response){
        log.info("会议数据导出请求进来~");
        ServletOutputStream out= null;
        try {
            List<Reservation> rows = reservationService.list();
            List<ExportReservation> list = new ArrayList<>();
            rows.stream().forEach(item -> {
                ExportReservation exportReservation = new ExportReservation();
                exportReservation.setTheme(item.getTheme());
                exportReservation.setRoomName(item.getRoomName());

                exportReservation.setRemark(item.getRemark());
                list.add(exportReservation);
            });
            System.out.println(list);
            ExcelWriter writer = ExcelUtil.getWriter(true);
            writer.write(list, true);
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
            String fileName = URLEncoder.encode("会议数据","UTF-8");
            response.setHeader("Content-Disposition","attachment;filename="+fileName+".xlsx");
            out = response.getOutputStream();
            writer.flush(out, true);
            writer.close();
            IoUtil.close(out);
            log.info("会议数据导出成功~");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
